package com.df.bpm.utils.businessViewer;

import com.df.bpm.dto.BusinessInformationDTO4Subset;
import com.df.bpm.dto.BusinessStepDTO;
import com.df.bpm.entity.BusinessEntity;
import com.df.bpm.entity.BusinessInformation;
import com.df.bpm.entity.BusinessLocations;
import com.df.bpm.utils.businessViewer.stepsTableServices.EntityService;
import com.df.bpm.utils.businessViewer.stepsTableServices.GroupService;
import com.df.bpm.utils.businessViewer.stepsTableServices.StepService;
import com.df.common.utils.CommonUtils;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.*;
import java.util.List;

/**
 * 业务内容（步骤）展示区
 * <P>1.内容分组管理</P>
 * <P>2.组内步骤管理</P>
 * <P>3.业务展开跳转</P>
 */
public class BusinessStepsTable extends JScrollPane {
    List<JTable> dataTables=new ArrayList<>();

    public Map<Integer,Map<Integer, BusinessStepDTO>> group_steps;


    JButton addGroup=new JButton("新分组");
    Integer newGroupID=null;

    BusinessInformation activeBusiness;
    GroupService groupService;
    StepService stepService;

    EntityService entityService;

    MainPanel daddy;

    int groupUIwidth;
    int unit;
    JPanel srcPanel;

    List<JScrollPane>groupUIs;

    int activeGroup;

    public BusinessStepsTable(MainPanel mainPanel){
        daddy=mainPanel;
        groupService=new GroupService(this);
        stepService=new StepService();
        entityService=new EntityService();
    }

    /**
     * 刷新
     */
    public void fresh(BusinessInformation business){
        activeBusiness=business;
        this.setBorder(BorderFactory.createTitledBorder(business.getBusinessDesc()));
        Integer superior=business.getBusinessInformationIndex();
        List<Integer> groups=groupService.getGroups(superior);
        groupUIs=new ArrayList<>();
        activeGroup=0;
        paintGroups(superior,groups);
    }

    /**
     * 画各组步骤前端界面
     * @param superior  分组的父级业务id
     * @param groups    分组id列表
     */
    public void paintGroups(Integer superior, List<Integer> groups) {
        unit= (int) MainPanel.unit;
        groupUIwidth=33*unit;
        group_steps=new HashMap<>();
        dataTables.clear();
        srcPanel=new JPanel();
//        srcPanel.setLayout(new FlowLayout(FlowLayout.LEFT, unit, unit));
        srcPanel.setLayout(null);
        for (int k=0;k<groups.size();k++){
            paintGroup(superior, groups, unit, k);
        }
        addGroup=new JButton("新分组");
        srcPanel.add(addGroup);
        addGroup.addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                groupService.newGroup(superior,groups);
            }
        });
        freshAddGroupButtonPos(groups);
    }

    private void freshAddGroupButtonPos(List<Integer> groups) {
        int xPos=unit;
        if(!groups.isEmpty()){
            JScrollPane lastGroupUI=groupUIs.get(groups.size()-1);
            xPos=lastGroupUI.getX()+lastGroupUI.getWidth()+unit;
        }
        addGroup.setBounds(xPos,unit,4*unit,2*unit);
        srcPanel.setPreferredSize(new Dimension((unit+addGroup.getX()+addGroup.getWidth()),
                (this.getHeight()-2*unit)));

        this.setViewportView(srcPanel);

        this.revalidate();
        this.repaint();
    }

    /**
     * 画新分组前端界面
     * @param superior  分组的父级业务id
     * @param groups    分组id列表
     */
    public void paintNewGroup(Integer superior, List<Integer> groups) {
        newGroupID=groups.get(groups.size()-1);
//        srcPanel.remove(addGroup);
        for (int k=groups.size()-1;k<groups.size();k++){
            paintGroup( superior, groups, unit, k);
        }
        freshAddGroupButtonPos(groups);
    }

    /**
     * 画分组界面
     * @param superior 分组的父级业务id
     * @param groups   分组id列表
     * @param unit     绘画的单位尺寸
     * @param k        groups中的序号
     */
    private void paintGroup( Integer superior, List<Integer> groups, int unit, int k) {
        Integer groupID=groups.get(k);
        Map<Integer, BusinessStepDTO> iSteps=stepService.getSteps(superior,groupID);
        if(iSteps==null){
            iSteps=new HashMap<>();
        }
        if(!iSteps.isEmpty()) {
            group_steps.put(groupID, iSteps);
        }
        String[] title={"businessID","步骤","业务","子集","担当主体","groupID","locationID"};//
        Object[][] info = new Object[iSteps.size()][title.length];
        for(Map.Entry<Integer, BusinessStepDTO> step : iSteps.entrySet()){
            int i=step.getKey()-1;
            info[i][0]=step.getValue().getBusiness().getBusinessInformationIndex();
            info[i][1]=step.getValue().getLocation().getSequence();
            info[i][2]=step.getValue().getBusiness().getBusinessDesc();
            info[i][3]=step.getValue().getBusiness().getSubset();
            BusinessEntity iEntity=entityService.getEntity(step.getValue().getBusiness().getEntityID());
            info[i][4]=iEntity.getName();
            info[i][5]=step.getValue().getLocation().getGroupID();
            info[i][6]=step.getValue().getLocation().getBusinessLocationsIndex();
        }

        DefaultTableModel iModel=new DefaultTableModel(info,title){
            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return false;//不允许编辑，留作触发双击或拖拽
            }
        };
        JTable iTable=new JTable(iModel);
        preAddStep(iSteps,iTable,superior,groupID);
        setTitleFont(iTable);
        setTableFont(iTable);
        iTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        iTable.getColumnModel().getColumn(1).setPreferredWidth(3*unit);
        iTable.getColumnModel().getColumn(2).setPreferredWidth(21*unit);
        iTable.getColumnModel().getColumn(3).setPreferredWidth(3*unit);
        iTable.getColumnModel().getColumn(4).setPreferredWidth(6*unit);
        Main.hideCol(iTable,0);
        Main.hideCol(iTable,5);
        Main.hideCol(iTable,6);
        iTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        dataTables.add(iTable);
        JScrollPane scr=new JScrollPane();
        int xPos=unit;
        if(k>0){
            xPos=groupUIs.get(k-1).getX()+groupUIs.get(k-1).getWidth()+unit;
        }
        scr.setLocation(xPos,unit);
        int iWidth=groupUIwidth;
        if(k!=activeGroup){
            iWidth= (int) (0.5*groupUIwidth);
        }
        scr.setSize(iWidth,this.getHeight()-scr.getY()-3*unit);
        srcPanel.add(scr);
        scr.getViewport().add(iTable);
        groupUIs.add(scr);
        Map<Integer, BusinessStepDTO> finalISteps = iSteps;
        iTable.addMouseListener(new MouseAdapter() {
            int hRow=-1;
            int tRow=-1;
            @Override
            public void mouseClicked(MouseEvent e) {
                int row = iTable.rowAtPoint(e.getPoint());
                int col = iTable.columnAtPoint(e.getPoint());
                if (row >= 0 ) {
                    BusinessLocations key= finalISteps.get(row+1).getLocation();
                    BusinessInformation value= finalISteps.get(row+1).getBusiness();
                    if (e.getClickCount() == 2) {// 处理双击事件
                        if(col==2){
                            editStepDesc(iTable,row,key,value);
                        }else if(col==4){
                            editStepEntity(iTable,row,key,value);
                        }
                    }else if(e.getClickCount() == 1){
                        if(value.getBusinessInformationIndex()!=null){
                            daddy.setFocusBusiness(value);
                            setFocusGroup(k);
                        }

                    }
                }
            }
            public void mousePressed(MouseEvent event)
            {
                try {
                    int iRow=iTable.getSelectedRow();
                    if(iRow>=0) {
                        hRow=iRow;
                    }
                } catch (Exception e) {
                    JOptionPane.showMessageDialog(null,e.getMessage(), "注意",JOptionPane.INFORMATION_MESSAGE);
                }
            }
            public void mouseReleased(MouseEvent event)
            {
                try {
                    int iRow=iTable.getSelectedRow();
                    if(iRow>=0) {
                        if(CommonUtils.varIsBlank(finalISteps.get(iRow+1).getLocation().getBusinessLocationsIndex())){
                            return;
                        }
                        tRow=iRow;
                        if(tRow!=hRow) {
                            updateStepSequence(hRow,tRow, finalISteps);
                        }
                        hRow=-1;
                        tRow=-1;
                    }
                } catch (Exception e) {
                    JOptionPane.showMessageDialog(null,e.getMessage(), "注意",JOptionPane.INFORMATION_MESSAGE);
                }
            }
        });
    }

    private void setFocusGroup(int k) {
        activeGroup=k;
        if(groupUIs!=null){
            for(int i=0;i<groupUIs.size();i++){
                if(CommonUtils.varIsBlank(groupUIs.get(i))){
                    continue;
                }
                int xPos=unit;
                if(i>0){
                    xPos=groupUIs.get(i-1).getX()+groupUIs.get(i-1).getWidth()+unit;
                }
                groupUIs.get(i).setLocation(xPos,unit);
                int iWidth=groupUIwidth;
                if(i!=activeGroup){
                    iWidth= (int) (0.5*groupUIwidth);
                }
                groupUIs.get(i).setSize(iWidth,this.getHeight()-groupUIs.get(i).getY()-3*unit);
            }
            int xPos=unit;
            JScrollPane lastGroupUI=groupUIs.get(groupUIs.size()-1);
            xPos=lastGroupUI.getX()+lastGroupUI.getWidth()+unit;
            addGroup.setBounds(xPos,unit,4*unit,2*unit);
            this.revalidate();
            this.repaint();
        }
    }

    /**
     * 修改步骤顺序
     * <P>head to tail（hRow2tRow）</P>
     * @param hRow 要修改的原始行
     * @param tRow  目标位置
     * @param iSteps 业务步骤列表
     */
    private void updateStepSequence(int hRow, int tRow, Map<Integer, BusinessStepDTO> iSteps) {
        stepService.updateStepSequence(hRow+1,tRow+1,iSteps.get(hRow).getLocation().getSuperior(),iSteps.get(hRow).getLocation().getGroupID());
        daddy.freshBusinessSteps(activeBusiness);
    }

    /**
     * 修改业务步骤对应的担当主体
     * @param iTable 被双击的table
     * @param row   被双击的行
     * @param step    对应的业务环节
     */
    private void editStepEntity(JTable iTable, int row, BusinessLocations location,BusinessInformation step) {
        BusinessEntity oldEntity=null;
        if(step.getEntityID()!=null){
            oldEntity=entityService.getEntity(step.getEntityID());
        }
        BusinessEntity newEntity=selectEntity(oldEntity);
        if(oldEntity==null || !Objects.equals(newEntity.getBusinessEntityIndex(), oldEntity.getBusinessEntityIndex())){
            step.setEntityID(newEntity.getBusinessEntityIndex());
            iTable.setValueAt(newEntity.getName(),row,4);
            updateStep(step,location);
        }
    }

    /**
     * 更新业务步骤信息
     * @param iStep 业务步骤信息
     * @param location 业务定位信息
     */
    private void updateStep(BusinessInformation iStep,BusinessLocations location) {
        Integer rows;
        if("-".equals(iStep.getBusinessDesc())) {
            rows=stepService.deleteStep(location);
        }else {
            rows=stepService.updateStep(iStep,location);
        }
        if(CommonUtils.varIsNotBlank(rows) && rows>0){
                if(CommonUtils.varIsNotBlank(newGroupID)
                && Objects.equals(newGroupID, location.getGroupID())){
                    newGroupID=null;//如果新分组有业务保存成功则更新主面板，以确保新增分组也有主面板的其它跳转功能
                }
            daddy.freshBusinessSteps(activeBusiness);

        }
    }

    /**
     * 弹窗筛选主体
     * @param oldEntity 旧主体
     * @return  筛选结果
     */
    private BusinessEntity selectEntity(BusinessEntity oldEntity) {
        Integer resultID=new EntityDialog(entityService).selectEntity(oldEntity);
        return entityService.getEntity(resultID);
    }

    /**
     * 修改业务步骤对应的业务描述
     * @param iTable 被双击的table
     * @param row   被双击的行
     * @param location    对应的业务定位
     * @param iStep    对应的业务步骤
     */
    private void editStepDesc(JTable iTable, int row, BusinessLocations location, BusinessInformation iStep) {
        String oldValue=""+iTable.getValueAt(row, 2);
        String tips="请输入此步骤的业务描述：";
        String newValue= (String) JOptionPane.showInputDialog(null, tips, "业务描述", JOptionPane.PLAIN_MESSAGE, null, null, oldValue);
        if(newValue!=null && !newValue.isEmpty() && !oldValue.equals(newValue)){
            iTable.setValueAt(newValue,row,2);
            iStep.setBusinessDesc(newValue);
            updateStep(iStep,location);
        }
    }

    /**
     * 预新增，以便编辑保存
     *
     * @param iSteps    业务步骤信息
     * @param iTable    展示的前端表格界面
     * @param superior  步骤所属父级业务ID
     * @param groupID   步骤所属分组ID
     */
    private void preAddStep(Map<Integer,BusinessStepDTO> iSteps,
                            JTable iTable, Integer superior, Integer groupID) {
        BusinessLocations preStep=new BusinessLocations();
        preStep.setSuperior(superior)
                .setGroupID(groupID)
                .setSequence(iSteps.size()+1);
        iSteps.put(iSteps.size()+1,new BusinessStepDTO(preStep,new BusinessInformationDTO4Subset()));//新增一组空值留便新增步骤
        DefaultTableModel model = (DefaultTableModel) (iTable.getModel());
        Object [] newRow = {null,preStep.getSequence(),"","",null};
        model.addRow(newRow);
    }


    /**
     * 调整标题字体
     */
    private void setTitleFont(JTable iTable){
        iTable.getTableHeader().setFont(new Font("宋体", Font.BOLD, (int) (MainPanel.unit*1.1)));
        iTable.getTableHeader().setReorderingAllowed(false);
    }

    /**
     * 调整table内容字体
     */
    private void setTableFont(JTable iTable){
        iTable.setFont(new Font("宋体", Font.PLAIN, (int) (MainPanel.unit)));
        iTable.setRowHeight((int) (MainPanel.unit+1));
    }

}
